<template>
  <page-card title="菜单管理"
             sub-title="编辑"
             :need-back="true">
    <a-form-model :model="form"
                  :label-col="{ span: 6 }"
                  :wrapper-col="{ span: 12 }"
                  ref="form"
                  :rules="{
                    name: [{required: true, message:'此项必填'}],
                    code: [{required: true, message:'此项必填'}],
                    uri: [{
                      required: true, message:'此项必填'
                    }, {
                      validator: validateURI, trigger: 'blur'
                    }]
                  }">
      <a-form-model-item label="上级菜单">
        <span>{{ parents.names.length==0?'无':parents.names.join('&nbsp;&nbsp;/&nbsp;&nbsp;') }}</span>
        <a-cascader @popupVisibleChange="onPopupVisibleChange"
                    @change="onParentChange"
                    :fieldNames="{label:'name', value:'id', children: 'children'}"
                    :changeOnSelect="true"
                    ref="parentCascader"
                    :options="parentTreeData">
          <a href="javascript:;;">
            <a-icon type="edit"
                    style="font-size: var(--font-size-18); margin-left: 10px;"
                    theme="filled" />
          </a>
        </a-cascader>
      </a-form-model-item>
      <a-form-model-item label="名称"
                         prop="name">
        <a-input v-model.trim="form.name"
                 :maxLength="20"
                 placeholder="不超过20字" />
      </a-form-model-item>
      <a-form-model-item v-if="showCategoryFormItem"
                         label="分类">
        <a-radio-group v-model="form.category"
                       :options="this.catatories" />
      </a-form-model-item>
      <a-form-model-item label="类型"
                         prop="type">
        <a-radio-group v-model="form.type"
                       :options="types"
                       @change="onTypeChange" />
      </a-form-model-item>
      <a-form-model-item label="打开方式">
        <a-radio-group v-model="form.target"
                       :options="this.targets"
                       @change="onTargetChange" />
      </a-form-model-item>
      <a-form-model-item label="编码"
                         help="只能包含字母、数字、减号或下划线"
                         prop="code">
        <a-input v-model="form.code"
                 :addon-before="parentCode"
                 @change="onCodeChange"
                 :maxLength="120" />
      </a-form-model-item>
      <a-form-model-item v-if="form.target == '1'"
                         label="PC端路由地址"
                         help="只能包含字母, 数字, 减号, 下划线, ?, &, =, /:，一般与编码保持一致即可"
                         prop="uri">
        <a-input v-model="form.uri"
                 :addon-before="parentURI"
                 :maxLength="30"
                 :isEdit="false"
                 @change="onURIChange"
                 ref="uriField" />
      </a-form-model-item>
      <a-form-model-item v-if="form.target != '1'"
                         label="跳转地址">
        <a-input v-model="form.uri"
                 :maxLength="200">
          <a-select v-model="uriType"
                    slot="addonBefore"
                    :dropdownMatchSelectWidth="false"
                    :options="parentURISelectOption" />
        </a-input>
      </a-form-model-item>
      <a-form-model-item v-if="uriType!='http://' && uriType!='https://'"
                         label="PC端页面组件"
                         help="访问路径对应页面组件的路径或名称(可选项有 RouteView, TabView )，一般如有下级菜单则设置为可选项组件">
        <a-input v-model="form.component"
                 :disabled="form.type=='1'"
                 :maxLength="250" />
      </a-form-model-item>
      <a-form-model-item label="移动端路由地址">
        <a-input v-model="form.mobileUri"
                 :maxLength="250" />
      </a-form-model-item>
      <a-form-model-item label="移动端页面组件">
        <a-input v-model="form.mobileComponent"
                 :maxLength="250" />
      </a-form-model-item>
      <a-form-model-item v-if="showIcon"
                         label="图标">
        <a-input v-model="form.icon"
                 :maxLength="30" />
      </a-form-model-item>
      <a-form-model-item label="排序号">
        <a-input-number v-model="form.orderNo"
                        :min="1"
                        :max="10000" />
      </a-form-model-item>
      <a-form-model-item v-if="form.target == '1'"
                         label="状态保持"
                         help="路由状态保持，一般列表页需设置为“是”">
        <z-switch-one-zero v-model="form.keepAlive"
                           checked-children="是"
                           un-checked-children="否" />
      </a-form-model-item>
      <a-form-model-item v-if="form.type != '3'"
                         label="是否隐藏"
                         help="是否在左侧菜单栏隐藏该菜单">
        <z-switch-one-zero v-model="form.hidden"
                           checked-children="是"
                           un-checked-children="否" />
      </a-form-model-item>
      <a-form-model-item label="是否启用">
        <z-switch-one-zero v-model="form.status"
                           checked-children="是"
                           un-checked-children="否" />
      </a-form-model-item>
      <a-form-model-item label="说明">
        <a-textarea :maxLength="120"
                    placeholder="菜单功能描述，不超过120字"
                    v-model="form.remark"
                    style="height:100px" />
      </a-form-model-item>
    </a-form-model>
    <div style="text-align:center">
      <a-button type="primary"
                action
                @click="handleSave"
                style="width:80px;">
        保存
      </a-button>
    </div>
  </page-card>
</template>

<script>

import ArrayUtil from '@zh/common-utils/utils/array'

import { saveOrUpdate, getById, getParentsById, getAll } from '../../api/menu/index'

export default {
  data () {
    return {
      parentName: null,
      apiUrlLabel: '',
      uriType: '',
      form: { type: '2', code: '', target: '1', status: '1', uri: '', component: '', hidden: '0' },
      parents: {
        category: '1',
        ids: [],
        names: [],
        codes: [],
        uris: []
      },
      parentTreeData: [],
      show: {
        microApp: true,
        hidden: true
      },
      types: [{
        label: '分类',
        value: '1'
      }, {
        label: '菜单',
        value: '2'
      }, {
        label: '功能',
        value: '3'
      }],
      catatories: [{
        label: '管理端',
        value: '1'
      }, {
        label: '用户端',
        value: '2'
      }],
      targets: [{
        label: '本应用',
        value: '1'
      }, {
        label: '内嵌',
        value: '2'
      }, {
        label: '新窗口',
        value: '3'
      }]
    }
  },
  computed: {
    showCategoryFormItem () {
      if (this.parents.ids.length == 0) {
        return true
      }
      return this.parents.ids[0] == '0'
    },
    showComponent () {
      return this.form.getFieldValue('type') != '1'
    },
    showIcon () {
      return this.parents.codes.length == 0
    },
    parentCode () {
      return `${this.parents.codes.join(':')}:`
    },
    parentURI () {
      if (this.uriType != 'http://' && this.uriType != 'https://') {
        return this.parents.uris.length > 0 ? `${this.parents.uris[this.parents.uris.length - 1]}/`.replace(/\/+/g, '/') : '/'
      }
      return this.uriType
    },
    parentURISelectOption () {
      const option = [{
        label: this.parents.uris.length > 0 ? `${this.parents.uris[this.parents.uris.length - 1]}/`.replace(/\/+/g, '/') : '/',
        value: this.parents.uris.length > 0 ? `${this.parents.uris[this.parents.uris.length - 1]}/`.replace(/\/+/g, '/') : '/'
      }, {
        label: 'http://',
        value: 'http://'
      }, {
        label: 'https://',
        value: 'https://'
      }]
      return option
    }
  },
  mounted () {
    const params = this.$route.query
    // 新增获取所有上级节点
    if (params.parentId || (!params.id && !params.parentId)) {
      getParentsById(params.parentId || '').then(response => {
        this.initParents(response.parentMenuList)
        if (!this.$route.query.id) {
          this.form.orderNo = response.orderNo
          this.form.category = this.parents.category
          this.form.parentId = this.parents.ids.length > 0 ? this.parents.ids[this.parents.ids.length - 1] : ''
        }
        this.initParentTreeData()
      })
    }

    if (params.id) {
      // 修改
      getById(params.id).then(response => {
        this.initParents(response.parentMenuList)
        response.uri = response.uri || ''
        if (response.uri.startsWith('http://')) {
          this.uriType = 'http://'
          response.uri = response.uri.replace(this.uriType, '')
        } else if (response.uri.startsWith('https://')) {
          this.uriType = 'https://'
          response.uri = response.uri.replace(this.uriType, '')
        } else {
          this.uriType = this.parentURI
          response.uri = response.uri.replace(this.parentURI, '')
          response.uri.startsWith('/') && (response.uri = response.uri.substring(1))
        }

        response.code = response.code.replace(this.parentCode, '')
        this.form = response

        this.initParentTreeData()
      })
    }
  },
  methods: {
    initParents (parents) {
      this.parents = {
        category: '1',
        ids: [],
        names: [],
        codes: [],
        uris: []
      }
      parents.map((p, index) => {
        this.parents.category = p.category
        this.parents.names.push(p.name)
        this.parents.codes.push(p.code.split(':').pop())
        this.parents.ids.push(p.id)
        if (p.target == '1') {
          const uri = p.uri.split('/')
          uri.length = index + 2
          this.parents.uris.push(uri.join('/'))
        }
      })
    },

    initParentTreeData () {
      getAll({ ...this.queryParams }).then((response) => {
        const excludeParentIds = [], ids = [], map = {}, dataList = []
        response.map((i) => {
          if (i.type == '3') {
            return
          }
          i.parentId == '0' && (i.parentId = null)
          i.value = i.id
          i.label = i.name
          ids.push(i.id)
          map[i.id] = {
            id: i.id,
            parentId: i.parentId,
            name: i.name,
            code: i.code,
            category: i.category,
            target: i.target,
            uri: i.uri
          }
        })
        ids.map(id => {
          // 排除本节点及其以下所有节点
          id == this.form.id && excludeParentIds.push(id)
          if (excludeParentIds.includes(map[id].parentId)) {
            excludeParentIds.push(id)
          }
          !excludeParentIds.includes(id) && dataList.push(map[id])
        })
        const { nodeList } = ArrayUtil.toTree(dataList, 'id', 'parentId')
        nodeList.splice(0, 0, {
          id: '0',
          parentId: null,
          name: '无',
          code: '',
          category: null,
          target: '1',
          uri: ''
        })
        this.parentTreeData = nodeList
      })
    },
    onPopupVisibleChange (isPopupVisible) {
      if (!isPopupVisible) {
        if (this.$refs.parentCascader.parents && this.$refs.parentCascader.parents.length > 0) {
          this.initParents(this.$refs.parentCascader.parents)
          this.form.parentId = this.parents.ids[this.parents.ids.length - 1]
        }
      }
    },
    onParentChange (keys, nodeDataList) {
      this.$refs.parentCascader.parents = nodeDataList
    },
    validateCode (rule, value, callback) {
      // if (value.trim().match(/\s/g)) {
      //   callback(new Error('编码不能包含空格'))
      // } else if (value.match(/[^a-zA-Z\d-_]+/g)) {
      //   callback(new Error('只能包含字母、数字、减号或下划线'))
      // } else {
      //   callback()
      // }
      callback()
    },
    onTargetChange (e) {
      if (this.form.target == '1') {
        this.uriType = this.parentURISelectOption[0].value
      } else {

      }
    },
    onCodeChange (e) {
      if (this.form.target != 1) {
        return
      }
      e.target.value = e.target.value.replace(/[`~!@#$%^&*()+=<>?:"{}|,./;'\\[\]·~！@#￥%……&*（）——+={}|《》？：“”【】、；‘’，。、]/g, '').replace(/\s/g, '')
      if (!this.$refs.uriField.isEdit && this.form.code != '' && e.target.value.startsWith(this.form.uri)) {
        this.form.uri = this.form.code
      }
      this.form.code = e.target.value
    },
    onURIChange (e) {
      if (this.form.target != 1) {
        return
      }
      e.target.value = e.target.value.replace(/[`~!@#$%^*()+<>"{}|,.;'\\[\]·~！@#￥%……*（）——+{}|《》？：“”【】、；‘’，。、\u4e00-\u9fa5]/g, '')
        .replace(/\s/g, '')
        .replace(/\/+/g, '/')
        .replace(/:+/g, ':')
        .replace(/^\/+/g, '')
      // .replace(/\/+:{0,}/g, '/:')
      // e.target.temp = e.target.value
      if (e.target.value != this.form.code || e.target.value == '') {
        this.$refs.uriField.isEdit = true
      } else {
        delete this.$refs.uriField.isEdit
      }
    },
    validateURI (rule, value, callback) {
      // if (value.length > 0) {
      //   const v = value.split('/:').find(i => i != '/' && i != ':' && (i.indexOf('/') != -1 || i.indexOf(':') != -1))
      //   if (v) {
      //     callback(new Error('路由地址 "/" 必须配合 "/:" 使用'))
      //     return
      //   }
      // }
      callback()
    },
    handleSave () {
      this.$refs.form.validate(ok => {
        if (!ok) {
          return
        }
        const formData = { ...this.form }
        formData.code = `${this.parentCode}${formData.code}`.replace(/^:+/, '')
        formData.uri = `${this.parentURI}${formData.uri}`
        saveOrUpdate(formData).then((response) => {
          this.$router.go(-1)
        })
      })
    },
    onTypeChange () {
      this.form.before_change_component = this.form.before_change_component || this.form.component
      if (this.form.type == '1') {
        this.form.component = 'RouteView'
      } else {
        this.form.component = this.before_change_component
      }
      if (this.form.type == '3') {
        this.form.hidden = '1'
      }
    }
  }
}
</script>

<style lang="less">
</style>
